/**
 * 
 */
package org.youisoft.summer.evaluator.unit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.youisoft.summer.evaluator.InvokeException;
import org.youisoft.summer.evaluator.UnitEnum;
import org.youisoft.summer.evaluator.context.CalContext;
import org.youisoft.summer.evaluator.operator.Operator;
import org.youisoft.summer.evaluator.operator.base.ClosureOperator;

/**
 * @author zijiang.jl
 *
 */
public abstract class AbstractParenthesis<R,P> extends AbstractCommonUnit<R,P> implements Parenthesis<R,P>{
	protected static final Log logger=LogFactory.getLog(Parenthesis.class);
	private java.lang.ThreadLocal<java.util.List<VisitorUnit<R, P>>> localBrackets=new java.lang.ThreadLocal<java.util.List<VisitorUnit<R, P>>>();
	@Override
	public void init() {
		super.init();
		if(this.getfName()==null||"".equals(this.getfName())) this.setfName(Parenthesis.class.getName());
		
	}

	@Override
	protected void checkLocalValue() {
		super.checkLocalValue();
		
		if(localBrackets.get()==null){
			localBrackets.set(new java.util.ArrayList<VisitorUnit<R, P>>());
		}
		localBrackets.get().clear();
	
	}
	
	@Override
	public <C> void accept(CalContext<C,R,P> context,UnitVisitor<R,P> visitor) throws InvokeException{
		logger.debug("accept visitor......");
		this.setProperty(visitor.getProperty());
		this.setResource(visitor.getResource());
		this.checkLocalValue();
		Iterator<VisitorUnit<R, P>> it=this.iterator();
		UnitEnum ue;
		while((ue=it.hasNext())!=null){
			switch(ue){
				case parenthesis:
					it.next().accept(context, visitor);
					this.addChildValue(visitor.getValue());
				break;
				case brace:
					VisitorUnit<R, P> vu=it.next();
					this.addChildValue(new ClosureOperator(vu.getContent()).setName(vu.getfName()).setRegistry(this.getRegistry()));
					break;
				case bracket:
					localBrackets.get().add(it.next());
					this.addChildValue(Operator.nullInstance);
					break;
				default:
			}
		}
		logger.debug("begin visit......"+this.getClass().getName());
		visitor.visit(context,this);
		for(int i=0;i<this.localBrackets.get().size();i++){
			this.localBrackets.get().get(i).accept(context, visitor);
		}
		logger.debug("end visit......");
	}
	


	@Override
	public UnitEnum getUnitType() {
		return UnitEnum.parenthesis;
	}

}
